/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.pc9.pswing.components;

import br.com.paulocanedo.pc9.laf.PBorder;
import br.com.paulocanedo.pc9.util.ComponentUtil;
import br.com.paulocanedo.third.effects.GraphicsUtilities;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.PanelUI;

/**
 *
 * @author paulocanedo
 */
public class SearchComponent {

    private JButton clearButton;
    private Icon emptyIcon = createEmptyIcon(16);
    private Icon clearIcon = createClearIcon(16, false);
    private Icon clearRolloverIcon = createClearIcon(16, true);
    private JPanel component = new JPanel();
    private JTextField searchField = new JTextField();
    private List<SearchTextChangedListener> listeners = new ArrayList<SearchTextChangedListener>();

    public SearchComponent() {
        searchField.putClientProperty("JComponent.type", "squared");
        searchField.putClientProperty("JTextField.segmentPosition", "first");
        searchField.putClientProperty("placeholder", "Pesquisar");
        searchField.addFocusListener(new SearchFocusAdapter());

        clearButton = new JButton();
        clearButton.setIcon(emptyIcon);
        clearButton.setRolloverIcon(emptyIcon);
        clearButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                searchField.setText("");
                searchField.grabFocus();
            }
        });
        clearButton.setBorderPainted(false);
        clearButton.setContentAreaFilled(false);
        clearButton.putClientProperty("borderFocus", Boolean.FALSE);

        searchField.getDocument().addDocumentListener(new DocumentListener() {

            private void updateClearButtonVisibility(DocumentEvent e) {
                boolean visible = e.getDocument().getLength() == 0;
                clearButton.setIcon(visible ? emptyIcon : clearIcon);
                clearButton.setRolloverIcon(visible ? emptyIcon : clearRolloverIcon);
            }

            private void fireSearchTextChanged() {
                for (SearchTextChangedListener listener : listeners) {
                    listener.textChanged(searchField.getText());
                }
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                updateClearButtonVisibility(e);
                fireSearchTextChanged();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateClearButtonVisibility(e);
                fireSearchTextChanged();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateClearButtonVisibility(e);
                fireSearchTextChanged();
            }
        });

        final JLabel label = new JLabel();
        label.setIcon(createSearchIcon(16));

        component.setLayout(new BoxLayout(component, BoxLayout.LINE_AXIS));
        component.add(Box.createRigidArea(new Dimension(6, 6)));
        component.add(label);
        component.add(searchField);
        component.add(clearButton);

        component.setBackground(Color.WHITE);
        component.setBorder(new PBorder());
        searchField.setBorder(new EmptyBorder(1, 5, 1, 1));
        component.setUI(new SearchPanelUI());
    }
    
    public void addActionListener(ActionListener listener) {
        searchField.addActionListener(listener);
    }
    
    public void removeActionListener(ActionListener listener) {
        searchField.removeActionListener(listener);
    }

    public void addActionListenerToClearButton(ActionListener listener) {
        clearButton.addActionListener(listener);
    }

    public void removeActionListenerToClearButton(ActionListener listener) {
        clearButton.removeActionListener(listener);
    }

    public void addSearchTextChangedListener(SearchTextChangedListener listener) {
        listeners.add(listener);
    }

    public void removeSearchTextChangedListener(SearchTextChangedListener listener) {
        listeners.remove(listener);
    }

    public JComponent getComponent() {
        return component;
    }

    public void setHintText(String text) {
        searchField.putClientProperty("JTextField.description", text);
    }

    public String getText() {
        return searchField.getText();
    }

    private class SearchPanelUI extends PanelUI {

        @Override
        public void update(Graphics g, JComponent c) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setColor(UIManager.getColor("control"));
            g2.fillRect(0, 0, c.getWidth(), c.getHeight());

            g2.setColor(Color.WHITE);
            RoundRectangle2D shape = ComponentUtil.getRoundedInteriorShape(c);
            ComponentUtil.fastFill(g2, shape);

            g2.dispose();
        }
    }

    private class SearchFocusAdapter extends FocusAdapter {

        @Override
        public void focusGained(FocusEvent e) {
            getComponent().putClientProperty("JComponent.forceBorderBlurred", Boolean.TRUE);
            getComponent().repaint();
        }

        @Override
        public void focusLost(FocusEvent e) {
            getComponent().putClientProperty("JComponent.forceBorderBlurred", Boolean.FALSE);
            getComponent().repaint();
        }
    }

    private Icon createClearIcon(int size, boolean hover) {
        BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(size, size);
        Graphics2D graphics = image.createGraphics();

        if (hover) {
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setColor(new Color(225, 225, 225, 200));
            graphics.fillOval(0, 0, size - 1, size - 1);
        }

        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        graphics.setStroke(new BasicStroke(2f));
        graphics.setColor(hover ? Color.BLACK : Color.GRAY);
        graphics.drawLine(4, 4, size - 6, size - 6);
        graphics.drawLine(size - 6, 4, 4, size - 6);

        return new ImageIcon(image);
    }

    private Icon createSearchIcon(int size) {
        BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(size, size);
        int x = 0, y = 0;

        Graphics2D g2 = (Graphics2D) image.getGraphics().create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setStroke(new BasicStroke(2f));
        g2.setColor(Color.GRAY);
        g2.drawLine(size - size / 2, size - size / 2, size, size);

        g2.setColor(Color.WHITE);
        g2.fillOval(x + 1, y + 1, size - size / 3, size - size / 3);

        g2.setColor(Color.GRAY);
        g2.drawOval(x + 1, y + 1, size - size / 3, size - size / 3);

        return new ImageIcon(image);
    }

    private Icon createEmptyIcon(int size) {
        BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(size, size);
        Graphics2D g2 = (Graphics2D) image.getGraphics().create();
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, size, size);
        return new ImageIcon(image);
    }

    public interface SearchTextChangedListener {

        public void textChanged(String newText);
    }
}
